#ifndef __BASIC__SINGLETON_H__
#define __BASIC__SINGLETON_H__

#include "basic/types.h"

namespace basic {
template <typename T>
class tpl_Singleton {
  M_DELETE_COPY_ASSIGN(tpl_Singleton<T>)

private:
  static T* s_ins;

public:
  static T* GetIns() {
    if (s_ins == nullptr) {
      s_ins = new T();
    }
    return s_ins;
  };

protected:
  tpl_Singleton() = default;
  virtual ~tpl_Singleton() = default;

  virtual void Init(){};
  virtual void DeInit(){};
};

template <typename T>
T* tpl_Singleton<T>::s_ins = nullptr;

#define M_SINGLETON_DECLARE(T)                                                                                         \
private:                                                                                                               \
  T(const T&) = delete;                                                                                                \
  T(const T&&) = delete;                                                                                               \
  T& operator=(const T&) = delete;                                                                                     \
  T() {                                                                                                                \
    Init();                                                                                                            \
  }                                                                                                                    \
  ~T() {                                                                                                               \
    DeInit();                                                                                                          \
  }                                                                                                                    \
  friend class tpl_Singleton<T>;
} // namespace basic

#endif
